﻿Public Class Simplex
    'buscar el negativo mayor
    'a partir de ahy se genera la ruta alternando signos + y - en cada esquina
    'buscar la menor asignacion de la ruta con signo -
    'sumar o restar dependiendo del signo de la ruta a la asignacion el valor encontrado en el paso anterior
    'verificar si es la asignacion optima
    'si aun existen verificaciones negativas repetir pasos anteriores
    Dim matrizMovimientos(3, 50) As Integer
    Dim matrizFinal(3, 50) As Integer
    Dim direccion As Integer
    Dim matrizDirecciones(50) As Integer
    Dim filamover As Integer
    Dim colmover As Integer
    Dim rutaNoValida As Boolean = False
    Public Function obtenerMovimientoInicial()
        Dim posicion(2) As Integer
        Dim valorMenor As Integer = 1000
        For i As Integer = 1 To grupbox1.empresas
            For j As Integer = 1 To grupbox1.bodegas
                For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                    If elemento.Name = "Panel" & i & j Then
                        If elemento.Controls.Item(0).Text <= valorMenor And elemento.Controls.Item(0).Text < 0 Then
                            valorMenor = elemento.Controls.Item(0).Text
                            posicion(0) = i
                            posicion(1) = j
                        End If
                    End If
                Next
            Next
        Next
        'la posicion donde se encuentra el menor de la verificación
        Return posicion
    End Function




    Public Function jugarSimplex(ByVal fila As Integer, ByVal columna As Integer, ByVal contadorRuta As Integer)
        Dim i As Integer
        Dim listo As Boolean = False
        'armar la matriz
        'Se marca la casilla como visitada 

        If esSolucion(contadorRuta) = True Then
            'MsgBox(fila & columna)
            'MsgBox("solucion")            
            'For i = 1 To contadorRuta - 1
            '    MsgBox(matrizMovimientos(1, i) & "x" & matrizMovimientos(2, i) & "x" & matrizMovimientos(3, i))
            'Next
            eliminarMovimientosDeMatriz(contadorRuta)
            Return True
        Else
            If contadorRuta = 1 Then
                matrizMovimientos(1, contadorRuta) = 0
                matrizMovimientos(2, contadorRuta) = fila
                matrizMovimientos(3, contadorRuta) = columna
                contadorRuta += 1
                For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                    If elemento.Name = "Panel" & fila & columna Then
                        elemento.Controls.Item(1).Text = 0
                    End If
                Next
            End If
            'ciclo hacia la derecha
            'For i = 1 To contadorRuta - 1
            '    MsgBox(matrizMovimientos(1, i) & "x" & matrizMovimientos(2, i) & "x" & matrizMovimientos(3, i))
            'Next
            'MsgBox(matrizDirecciones(contadorRuta))
            If matrizDirecciones(contadorRuta) <> 3 Then
                i = columna
                While (i <= grupbox1.bodegas)
                    For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                        If elemento.Name = "Panel" & fila & i + 1 Then
                            'MsgBox(elemento.Controls.Item(1).Text & " fila " & fila & " columna " & i + 1)
                            If elemento.Controls.Item(1).Text <> "" And elemento.Controls.Item(1).Text <> "label3" Then
                                ReDim Preserve matrizMovimientos(3, contadorRuta)
                                matrizMovimientos(1, contadorRuta) = elemento.Controls.Item(1).Text
                                matrizMovimientos(2, contadorRuta) = fila
                                matrizMovimientos(3, contadorRuta) = i + 1
                                contadorRuta += 1
                                direccion = 1
                                ReDim Preserve matrizDirecciones(contadorRuta)
                                matrizDirecciones(contadorRuta) = 1
                                If jugarSimplex(fila, i + 1, contadorRuta) = True Then
                                    Return True
                                Else
                                    direccion = 1
                                    'MsgBox("derecha")
                                    contadorRuta -= 1
                                    ReDim Preserve matrizMovimientos(3, contadorRuta)
                                    ReDim Preserve matrizDirecciones(contadorRuta)
                                End If
                            End If
                        End If
                    Next
                    i += 1
                End While
            End If
            'ciclo hacia abajo
            If matrizDirecciones(contadorRuta) <> 4 Then
                i = fila
                While (i <= grupbox1.empresas)
                    For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                        If elemento.Name = "Panel" & i + 1 & columna Then
                            'MsgBox(elemento.Controls.Item(1).Text & " fila " & i + 1 & " columna " & columna)
                            If elemento.Controls.Item(1).Text <> "" And elemento.Controls.Item(1).Text <> "label3" Then
                                'MsgBox(elemento.Controls.Item(1).Text)
                                ReDim Preserve matrizMovimientos(3, contadorRuta)
                                matrizMovimientos(1, contadorRuta) = elemento.Controls.Item(1).Text
                                matrizMovimientos(2, contadorRuta) = i + 1
                                matrizMovimientos(3, contadorRuta) = columna
                                contadorRuta += 1
                                direccion = 2
                                ReDim Preserve matrizDirecciones(contadorRuta)
                                matrizDirecciones(contadorRuta) = 2
                                If jugarSimplex(i + 1, columna, contadorRuta) = True Then
                                    Return True
                                Else
                                    'MsgBox("abajo")
                                    direccion = 2
                                    contadorRuta -= 1
                                    ReDim Preserve matrizMovimientos(3, contadorRuta)
                                    ReDim Preserve matrizDirecciones(contadorRuta)
                                End If
                            End If
                        End If
                    Next
                    i += 1
                End While
            End If
            'ciclo izquierda
            If matrizDirecciones(contadorRuta) <> 1 Then
                i = columna
                While (i >= 1)
                    For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                        If elemento.Name = "Panel" & fila & i - 1 Then
                            'MsgBox(elemento.Controls.Item(1).Text & " fila " & fila & " columna " & i - 1)
                            If elemento.Controls.Item(1).Text <> "" And elemento.Controls.Item(1).Text <> "label3" Then
                                ReDim Preserve matrizMovimientos(3, contadorRuta)
                                matrizMovimientos(1, contadorRuta) = elemento.Controls.Item(1).Text
                                matrizMovimientos(2, contadorRuta) = fila
                                matrizMovimientos(3, contadorRuta) = i - 1
                                contadorRuta += 1
                                direccion = 3
                                ReDim Preserve matrizDirecciones(contadorRuta)
                                matrizDirecciones(contadorRuta) = 3
                                If jugarSimplex(fila, i - 1, contadorRuta) = True Then
                                    Return True
                                Else
                                    'MsgBox("izquierda")
                                    direccion = 3
                                    contadorRuta -= 1
                                    ReDim Preserve matrizMovimientos(3, contadorRuta)
                                    ReDim Preserve matrizDirecciones(contadorRuta)
                                End If
                            End If
                        End If
                    Next
                    i -= 1
                End While
            End If
            'ciclo arriba
            If matrizDirecciones(contadorRuta) <> 2 Then
                i = fila
                While (i >= 1)
                    For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                        If elemento.Name = "Panel" & i - 1 & columna Then
                            'MsgBox(elemento.Controls.Item(1).Text & " fila " & i - 1 & " columna " & columna)
                            If elemento.Controls.Item(1).Text <> "" And elemento.Controls.Item(1).Text <> "label3" Then
                                ReDim Preserve matrizMovimientos(3, contadorRuta)
                                matrizMovimientos(1, contadorRuta) = elemento.Controls.Item(1).Text
                                matrizMovimientos(2, contadorRuta) = i - 1
                                matrizMovimientos(3, contadorRuta) = columna
                                contadorRuta += 1
                                direccion = 4
                                ReDim Preserve matrizDirecciones(contadorRuta)
                                matrizDirecciones(contadorRuta) = 4
                                If jugarSimplex(i - 1, columna, contadorRuta) = True Then
                                    Return True

                                Else

                                    'MsgBox("arriba")
                                    direccion = 4
                                    contadorRuta -= 1
                                    ReDim Preserve matrizMovimientos(3, contadorRuta)
                                    ReDim Preserve matrizDirecciones(contadorRuta)
                                    Return False
                                End If
                            End If
                        End If
                    Next
                    i -= 1
                End While
            End If
            'revisar la condición dle listo
        End If


        rutaNoValida = True
        ReDim Preserve matrizDirecciones(contadorRuta - 1)
        Return False
        Exit Function
    End Function
    Private Function esSolucion(ByVal contadorRuta As Integer)

        If matrizMovimientos(2, 1) = matrizMovimientos(2, contadorRuta - 1) And matrizMovimientos(3, 1) = matrizMovimientos(3, contadorRuta - 1) And (contadorRuta - 1) >= 4 Then
            'tenemos la matriz y comenzamos a eliminar las asignaciones de al medio
            'hacemos los cambios
            'For i = 0 To contadorRuta - 1
            '    MsgBox(matrizMovimientos(1, i)&" "&matrizMovimientos(2, i)& " "&matrizMovimientos(3, i) )
            'Next
            Return True
        Else
            Return False
        End If
        'la posicion donde se encuentra el menor de la verificación
    End Function
    Private Sub eliminarMovimientosDeMatriz(ByVal contadorRuta As Integer)
        Dim posicionesNoCopiar(1) As Integer
        Dim contadorPosicionesNoCopiar As Integer = 1
        'For i = 1 To contadorRuta - 1
        '    MsgBox(matrizMovimientos(1, i) & "x" & matrizMovimientos(2, i) & "x" & matrizMovimientos(3, i))
        'Next
        'toma las posiciones que no se copiaran a la nueva matriz
        For i = 1 To contadorRuta - 1
            If i + 1 < contadorRuta - 1 And i + 2 < contadorRuta - 1 Then
                'en el caso de las filas
                If matrizMovimientos(2, i) = matrizMovimientos(2, i + 1) And matrizMovimientos(2, i) = matrizMovimientos(2, i + 2) Then
                    posicionesNoCopiar(contadorPosicionesNoCopiar) = i + 1
                    contadorPosicionesNoCopiar += 1
                    ReDim Preserve posicionesNoCopiar(contadorPosicionesNoCopiar)
                    'evaluar como va en el caso de las columnas o sea en la posición 3 con un if o else if?, claro..
                ElseIf matrizMovimientos(3, i) = matrizMovimientos(3, i + 1) And matrizMovimientos(3, i) = matrizMovimientos(3, i + 2) Then
                    posicionesNoCopiar(contadorPosicionesNoCopiar) = i + 1
                    contadorPosicionesNoCopiar += 1
                    ReDim Preserve posicionesNoCopiar(contadorPosicionesNoCopiar)
                End If
            End If
        Next

        'hacer la copia manual a una nueva matriz que será la solución definitiva, revisar cuando este
        'vacio
        'For j = 1 To contadorPosicionesNoCopiar - 1
        '    MsgBox(posicionesNoCopiar(j))
        'Next
        Dim contadorDeMovimientosValidos As Integer = 1
        If contadorPosicionesNoCopiar <> 1 Then
            Dim j As Integer = 1
            For i = 1 To contadorRuta - 1
                If i <> posicionesNoCopiar(j) Then
                    matrizFinal(1, contadorDeMovimientosValidos) = matrizMovimientos(1, i)
                    matrizFinal(2, contadorDeMovimientosValidos) = matrizMovimientos(2, i)
                    matrizFinal(3, contadorDeMovimientosValidos) = matrizMovimientos(3, i)
                    contadorDeMovimientosValidos += 1
                Else
                    j += 1
                End If
            Next

        Else
            matrizFinal = matrizMovimientos.Clone()
        End If

        If contadorDeMovimientosValidos = 1 Then
            contadorDeMovimientosValidos = contadorRuta - 1
        End If
        'recorrer matriz final buscando el menor valor de pocicion par
        'For i = 1 To contadorRuta - 1
        '    MsgBox(matrizFinal(1, i) & "x" & matrizFinal(2, i) & "x" & matrizFinal(3, i))
        'Next
        Dim valormover As Integer = 1000
        For i = 1 To contadorDeMovimientosValidos - 1
            If matrizFinal(1, i) < valormover And i Mod 2 = 0 Then
                valormover = matrizFinal(1, i)
                'almacenar pocicion del valor a mover, ya que el valor de ese panel desaparece quedando = ""
                filamover = matrizFinal(2, i)
                colmover = matrizFinal(3, i)
            End If
        Next
        'MsgBox(valormover & "x" & filamover & "x" & colmover)
        'sumar o restar el menor valor encontrado en la matriz segun corresponda
        For i = 1 To contadorDeMovimientosValidos - 1
            If i Mod 2 = 0 Then
                matrizFinal(1, i) = matrizFinal(1, i) - valormover
            Else
                matrizFinal(1, i) = matrizFinal(1, i) + valormover
            End If
        Next
        'debemos llamr a la función acá de cargar la matriz en los paneles?, yep..
        cargarMatrizEnPaneles(contadorDeMovimientosValidos)
    End Sub
    Private Sub cargarMatrizEnPaneles(ByVal movimientosValidos As Integer)
        For i = 1 To movimientosValidos - 1
            For Each elemento As Control In grupbox1.splitContainer1.Panel1.Controls
                If elemento.Name = "Panel" & filamover & colmover Then
                    elemento.Controls.Item(1).Text = ""
                ElseIf elemento.Name = "Panel" & matrizFinal(2, i) & matrizFinal(3, i) Then
                    elemento.Controls.Item(1).Text = matrizFinal(1, i)
                End If
            Next
        Next
    End Sub
End Class
